package com.contexttree.gui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import com.contexttree.db.DatabaseManager;
import com.contexttree.filereader.QueryBuilder;
import com.contexttree.filereader.ReadCsvFile;
import com.contexttree.filereader.ReadTxtFile;
import com.contexttree.utils.FilePrinter;
import com.contexttree.utils.Printer;

/**
 * This class generate on console the menu for the context-tree application
 * Politecnico di Milano 2012
 * @author Paolo Barbaglia
 * @author Filippo Ferrari
 *
 */
public class TextualView {
	//Init local variables
	ArrayList<String> csvFile = new ArrayList<String>();
	String[][] csvFileSplitted = null;
	ArrayList<String> txtFile = new ArrayList<String>();
	ArrayList<String> txtFileOrdered = new ArrayList<String>();
	ArrayList<String> csvFilePos = new ArrayList<String>();
	ArrayList<String> csvFileNeg = new ArrayList<String>();
	ArrayList<String> csvFileConcat = new ArrayList<String>();
    ArrayList<String> concatMovie = new ArrayList<String>();
    String[][] tableOrdered = null;
    String[][] viewsOrdered = null;
    String queryFile = null;
	
	static int numID = 0;
	static int whileselect = 0;
	static String pathcsv = null;
	static String pathtxt = null;
	static String pathquery = null;
	String folderpath = null;
	static String switchsel = null;
	static String switchseltxt = null;
	static String selectQuery = null;
	static String queryString = null;
    String executableQueryPos = "";
    String executableQueryNeg = "";
    String tableNameField = "";
    String keyTableField = "";
    String selectQueryField = "";
    String databaseName = "";
    String databaseUser = "";
    String databasePass = "";
    DatabaseManager db = null;
    ArrayList<String> resultSetPos = null;
    ArrayList<String> resultSetNeg = null;
	
	//Variable for read input stream
    static InputStreamReader reader = new InputStreamReader (System.in);
    static BufferedReader myInput = new BufferedReader (reader);
	
	public void start(int whileselect) throws IOException{
		contextTreeLogo();
		menuReadFiles();
		
		while(whileselect==0){
	        generateConsoleMenu();
	        
	        switchsel = myInput.readLine();
	        switch(switchsel){
	        case "1":
	        	processCsv();
	        	break;
	        case "2": 
	        	processTxt();
	        	break;
	        case "3":
	        	generateQuery();
	        	break;
	        case "4":
	        	executeQuery();
	        	break;
	        case "5": 
	        	//Ricomincio l'acquisizione
	        	break;
	        case "6": 
	        	//Exit from program
	        	menuExit(whileselect);
	        default: 
	        	//default selection
	        	Printer.print("Wrong choice");
	        };
		}
	}
	
	protected void generateConsoleMenu(){
		//Menu generator
        Printer.print("\nSelect");
        Printer.print("[1] Process CSV");
        Printer.print("[2] Process TXT");
        Printer.print("[3] Generate query");
        Printer.print("[4] Execute query");
        Printer.print("[5] Restart");
        Printer.print("[6] Quit");
	}
	
	protected void menuReadFiles() throws IOException{
    	//The csv file is loaded
        Printer.print("Inserisci il percorso del file csv");
        pathcsv = myInput.readLine();
        csvFile = ReadCsvFile.read(pathcsv);
        //Check read
        if (csvFile != null){
        	Printer.print("Il file � stato letto correttamente");
        }
        
        //The txt file is loaded
        Printer.print("Inserisci il percorso del file txt");
        pathtxt = myInput.readLine();
        txtFile = ReadTxtFile.read(pathtxt);
        //Check read
        if (txtFile != null){
        	Printer.print("Il file � stato letto correttamente");
        }
        
        //The query file is loaded
        Printer.print("Inserisci il percorso del file delle query");
        pathquery = myInput.readLine();
        queryFile = QueryBuilder.readQueryFile(pathquery);
        //Check read
        if (queryFile != null){
        	Printer.print("Il file � stato letto correttamente");
        }
	}
	
	protected void processCsv(){
		Printer.print("====================== Conta record ======================\n");
		
        if (csvFile != null){
        	numID = ReadCsvFile.countId(csvFile);
        	csvFileSplitted = ReadCsvFile.checkRecords(csvFile, numID);
        	Printer.print("Il file � stato letto correttamente e contiene " + numID + " record distinti\n");
        	Printer.print("====================== Riordina csv ======================\n");
			ReadCsvFile.print(csvFileSplitted,csvFile,numID,null);
        }
        Printer.print("==========================================================\n");
	}
	
	protected void processTxt(){
		Printer.print("====================== Riordina txt ======================\n");
		txtFileOrdered = ReadTxtFile.order(txtFile);
		for(int i=0;i<txtFileOrdered.size();i++){
			Printer.print(txtFileOrdered.get(i)+"\n");
		}
		Printer.print("=============== Riordina txt per copertura ===============\n");
		ReadTxtFile.orderViews(csvFileSplitted, txtFileOrdered, null);
		Printer.print("=================== Elimina ridondanze ===================\n");
		ReadTxtFile.removeRedundantViews(txtFileOrdered, csvFileSplitted, null);
		Printer.print("==================== Conta occorrenze ====================\n");
        txtFileOrdered = ReadTxtFile.order(txtFile);
        tableOrdered = ReadTxtFile.orderRecords(csvFileSplitted, txtFileOrdered, null);
        Printer.print("==========================================================\n");
	}
	
	protected void generateQuery() throws IOException{
		Printer.print("Inserisci il nome della tabella");
		tableNameField = myInput.readLine();
		Printer.print("Inserisci il nome del campo chiave");
		keyTableField = myInput.readLine();
		Printer.print("Inserisci la query di estrazione (su una sola riga)");
		selectQueryField = myInput.readLine();
		Printer.print("====================== Genera query (IN) ======================\n");
		executableQueryPos = QueryBuilder.buildQuery(tableNameField, keyTableField, queryFile, selectQueryField, "IN");
		Printer.print(executableQueryPos);
		Printer.print("\n==================== Genera query (NOT IN) ====================\n");
		executableQueryNeg = QueryBuilder.buildQuery(tableNameField, keyTableField, queryFile, selectQueryField, "NOT IN");
		Printer.print(executableQueryNeg);
		Printer.print("\n===============================================================\n");
	}

	protected void executeQuery() throws IOException{
		//Prima genero la query poi mi collego al db e la eseguo
		generateQuery();
		//Connessione al database
		Printer.print("Inserisci il nome del database");
		databaseName = myInput.readLine();
		Printer.print("Inserisci il nome utente");
		databaseUser = myInput.readLine();
		Printer.print("Inserisci la password");
		databasePass = myInput.readLine();
		//l'utente sceglie il percorso dove verranno salvati i file di output
		Printer.print("Inserisci il percorso per il salvataggio dei file di output");
		folderpath = myInput.readLine();
		db = new DatabaseManager(databaseName, databaseUser, databasePass);
		if(db.isConnected()==false){
			db.connect();
			if (!db.connect()) {
				Printer.print("Errore durante la connessione.\n");
				Printer.print(db.getError());
			}else{
				Printer.print("====================== DB Status ======================\n");
				Printer.print("Connessione OK\n");
				executeQueryPhase2();
			}
		}
	}
	
	protected void executeQueryPhase2(){
		Printer.print("====================== Esegui query (IN) ======================\n");
		resultSetPos = db.executeQuery(executableQueryPos);
		String pathPos = FilePrinter.printResultQueryOnFile("positivi.csv",folderpath,resultSetPos);
		Printer.print("File creato: " + pathPos + "\n");
		Printer.print("Tracciato file: " + resultSetPos.get(0)+"\n");
		Printer.print("==================== Esegui query (NOT IN) ====================\n");
		resultSetNeg = db.executeQuery(executableQueryNeg);
		String pathNeg = FilePrinter.printResultQueryOnFile("negativi.csv",folderpath,resultSetNeg);
		Printer.print("File creato: " + pathNeg + "\n");
		Printer.print("Tracciato file: " + resultSetNeg.get(0)+"\n");
		
		csvFilePos=ReadCsvFile.read(pathPos);
		csvFileNeg=ReadCsvFile.read(pathNeg);
		csvFilePos=ReadCsvFile.addFieldPositive(csvFilePos);
		csvFileNeg=ReadCsvFile.addFieldUnlabeled(csvFileNeg);
		csvFileConcat=ReadCsvFile.concatenate(csvFilePos, csvFileNeg);
		numID=ReadCsvFile.countId(csvFileConcat);
		csvFileSplitted=ReadCsvFile.checkRecords(csvFileConcat, numID);
		csvFileSplitted=ReadCsvFile.arrangeId(csvFileSplitted);
		csvFileSplitted=ReadCsvFile.eliminateHeaders(csvFileSplitted);
		FilePrinter.printTable("Table.csv",folderpath, csvFileSplitted);
		csvFileSplitted=ReadCsvFile.convertToNumber(csvFileSplitted,folderpath,"");  //completareeee
	}
	
	protected static void contextTreeLogo() {
		Printer.print("###############################");
		Printer.print("#                             #");
		Printer.print("#    ContextTree Analisys     #");
		Printer.print("#                             #");
		Printer.print("###############################");
	}
	
	protected static void menuExit(int whileselect){
		whileselect = 1;
    	System.exit(0);
	}
}